package com.loukou.lkt.web.interceptor;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.loukou.lkt.cache.CacheService;
import com.loukou.lkt.cache.CompanyCache;
import com.loukou.lkt.lkt.datasource.DynamicDataSourceHolder;
import com.loukou.lkt.lkt.redis.RedisService;
import com.loukou.lkt.lkt.resp.AuthInfo;
import com.loukou.lkt.web.annotation.AuthCheck;
import com.loukou.lkt.web.resp.RespPureDto;

public class AuthInterceptor extends HandlerInterceptorAdapter {
	@Autowired
	private CompanyCache companyCache;
	@Autowired
	private RedisService redisService;
	@Autowired
	private CacheService cacheService;
	
	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		if (handler.getClass().isAssignableFrom(HandlerMethod.class)) {
			HandlerMethod handlerMethod = (HandlerMethod) handler;
			AuthCheck beanCheck = handlerMethod.getBean().getClass().getAnnotation(AuthCheck.class);
			AuthCheck methodCheck = handlerMethod.getMethodAnnotation(AuthCheck.class);
			HttpSession session = request.getSession();
			AuthInfo authInfo = null;
			if(session != null){
				authInfo = redisService.getAuthInfo(session.getId());
			}
			
			if(authInfo!=null){
				DynamicDataSourceHolder.putDataSourceName(cacheService.getDynamicDataSourceKey(authInfo.getCompanyDatabaseId()));
			}
			
			//需要的权限
			List<String> needPrivileges = new ArrayList<String>();
			if(beanCheck != null){
				String[] privileges = beanCheck.privileges();
				if(privileges != null){
					for(int i=0; i<privileges.length; i++){
						if(needPrivileges.contains(privileges[i])){
							needPrivileges.add(privileges[i]);
						}
					}
				}
			}
			if(methodCheck != null){
				String[] privileges = methodCheck.privileges();
				if(privileges != null){
					for(int i=0; i<privileges.length; i++){
						if(needPrivileges.contains(privileges[i])){
							needPrivileges.add(privileges[i]);
						}
					}
				}
			}
			boolean canVisit = false;
			if(beanCheck == null && methodCheck == null){
				canVisit = true;
			}else{
				if(authInfo != null){
					if(needPrivileges.size() == 0){
						canVisit = true;
					}else{
						for (int i = 0; i < needPrivileges.size(); i++) {
							if (authInfo.getPrivileges().contains(needPrivileges.get(i))) {
								canVisit = true;
							}
						}
					}
				}
			}
			if(canVisit){
				return true;
			}else{
				AuthCheck redirectAuthCheck = methodCheck;
				if(methodCheck == null){
					redirectAuthCheck = beanCheck;
				}
				if (redirectAuthCheck.isRedirect()) {
					if(authInfo == null){
						response.sendRedirect("login");
					}else{
						response.sendRedirect("no_priv");
					}
				} else {
					ObjectMapper objectMapper = new ObjectMapper();
					String json = "";
					if(authInfo == null){
						json = objectMapper.writeValueAsString(new RespPureDto(401, "not logon"));
					}else{
						json = objectMapper.writeValueAsString(new RespPureDto(402, "No Permission"));
					}
					response.getWriter().write(json);
					response.flushBuffer();
				}
			}
		}
		return false;
	}

	@Override
	public void postHandle(HttpServletRequest request,
		HttpServletResponse response, Object handler,
		ModelAndView modelAndView) throws Exception {
	}
}